package com.rmv.ums.request;

import java.io.IOException;
import java.util.Iterator;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

import com.rmv.ums.condition.Condition;
import com.rmv.ums.configuration.Configuration;
import com.rmv.ums.response.Response;

public class DefaultRequest extends AbstractRequest {

	private static final Logger logger = Logger.getLogger(DefaultRequest.class);

	public boolean process(HttpServletRequest req, HttpServletResponse resp) throws IOException {

		if (logger.isDebugEnabled())
			logger.debug("trying to match request with request:" + this.getId());

		if (this.match(req)) {

				
			logger.info("match found for request - matched request:" + this);

			// checks
			if (!check(req)) {
				logger.warn("incorrect checking for request - checks:" + this.getCheck());
				Response response = badCheckResponse != null ? badCheckResponse : Configuration.getInstance().getBadCheckDefaultResponse();
				response.process(req, resp);
				return false;
			}

			if (logger.isDebugEnabled())
				logger.debug("check correct for request - checks:" + this.getCheck());

			// response
			this.response.process(req, resp);

			logger.info("processed request with matched request:" + this.getId());

			return true;
		} else {
			if (logger.isDebugEnabled())
				logger.debug("request doesn't match request:" + this.getId());
			return false;
		}
	}

	private boolean match(HttpServletRequest req) {
		if (logger.isDebugEnabled())
			logger.debug("trying to match request with:" + this.getMatch());
		return checkConditions(req, match,true, false);
	}

	private boolean check(HttpServletRequest req) {
		if (logger.isDebugEnabled())
			logger.debug("checking request with:" + this.getCheck());
		return checkConditions(req, check,false, true);
	}

	private boolean checkConditions(HttpServletRequest req, Set conditions, boolean failFast, boolean alert) {
		boolean ok = true;
		for (Iterator iterator = conditions.iterator(); iterator.hasNext();) {
			Condition condition = (Condition) iterator.next();
			if (!condition.check(req)) {
				ok = false;
				if(alert) logger.info("request doesn't fulfill condition:" + condition);
				if (failFast)
					break;
			}
		}
		return ok;
	}

}
